package com.ling.module1sbbyyds.service.user;

import com.alibaba.fastjson.JSON;
import com.github.yitter.idgen.YitIdHelper;
import com.ling.sbbyyds.entity.users.User;
import com.ling.sbbyyds.interaction.param.LoginUser;
import com.ling.module1sbbyyds.utils.JWTUtils;
import com.ling.module1sbbyyds.utils.RedisDataUtil;
import com.ling.module1sbbyyds.utils.UserThreadLocal;
import com.ling.module1sbbyyds.utils.ValidateCode;
import com.ling.sbbyyds.interaction.ResultVo;
import com.ling.sbbyyds.mapper.user.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 天道酬勤、学无止境
 *
 * @Description: 类描述   登录
 * @author: ling
 * @date: 2022年03月08日
 */
@Slf4j
@Service
public class LoginService {
    @Autowired(required = false)
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate<String, String> redis;
    @Autowired
    private RedisDataUtil redisDataUtil;
    /**
     * 手机号正则
     */
    private String phoneStyle = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$";

    /**
     * 注入验证码工具类
     */
    @Autowired
    private ValidateCode validateCode;

    /**
     * @param loginUser: 手机号+验证码
     * @Description: 验证码登录/注册
     * @author: ling
     * @date: 2022/3/27
     * @Return: com.ling.module1sbbyyds.interaction.Return.Result
     */
    public ResultVo codeLogin(LoginUser loginUser) {
        if (loginUser.getCode() == null || loginUser.getPhone() == null) {
            return ResultVo.fail("参数不全！");
        }
        if (!loginUser.getPhone().matches(this.phoneStyle)) {
            return ResultVo.fail("手机号格式不正确！");
        }
        if (!redisDataUtil.verifyCode(loginUser.getCode(), loginUser.getPhone())) {
            return ResultVo.fail("验证码错误！");
        }
        //默认是登录标志
        boolean flag = true;
        //根据手机号获取用户信息
        User oldUser = userMapper.findUserByPhone(loginUser.getPhone());
        //手机号没注册就调用注册方法
        if (oldUser == null) {
            oldUser = enroll(loginUser);
            if (ObjectUtils.isEmpty(oldUser)) {
                return ResultVo.fail("注册失败！");
            }
            //进行注册标注
            flag = false;
        }
        //将登录成功的用户id存进token
        String token = JWTUtils.createToken(oldUser.getId());
        //存进redis,token为键,用户信息为值
        redis.opsForValue().set(token, JSON.toJSONString(oldUser), 1, TimeUnit.DAYS);
        //返回token
        if (flag) {
            return ResultVo.success(token, "登录成功！");
        }
        return ResultVo.success(token, "注册成功！");
    }

    /**
     * @param loginUser: 手机号+密码
     * @Description: 密码登录
     * @author: ling
     * @date: 2022/3/27
     * @Return: com.ling.module1sbbyyds.interaction.Return.Result
     */
    public ResultVo passwordLogin(LoginUser loginUser) {
        try {
            if (loginUser.getPassword() == null || loginUser.getPhone() == null) {
                return ResultVo.fail("参数不全！");
            }
            if (!loginUser.getPhone().matches(this.phoneStyle)) {
                return ResultVo.fail("手机号格式不正确！");
            }
            User user = new User();
            BeanUtils.copyProperties(loginUser, user);
            User login = userMapper.findLogin(user);
            if (login != null) {
                //将登录成功的用户id存进token
                String token = JWTUtils.createToken(login.getId());
                //存进redis,token为键,用户信息为值
                redis.opsForValue().set(token, JSON.toJSONString(login), 30, TimeUnit.DAYS);
                return ResultVo.success(token);
            } else {
                return ResultVo.fail("账号或密码错误！");
            }
        } catch (Exception e) {
            log.error("密码登录时出现内部错误！");
            e.printStackTrace();
            return ResultVo.fail();
        }

    }

    /**
     * 默认头像
     */
    @Value("${defaul.userAvatar}")
    String defaultUserAvatar;

    /**
     * @param loginUser:
     * @Description: 用户注册
     * @author: ling
     * @date: 2022/3/27
     * @Return: com.ling.module1sbbyyds.pojo.User
     */
    public User enroll(LoginUser loginUser) {
        try {
            User user = new User();
            BeanUtils.copyProperties(loginUser, user);
            //初始化用户
            long newId = YitIdHelper.nextId();
            user.setId(newId);
            //随机生成用户名
            user.setUserName("用户" + validateCode.getCode());
            //随机生成密码
            user.setPassword("" + validateCode.getCode() + validateCode.getCode());
            user.setSex("隐藏");
            //默认头像
            user.setAvatar(defaultUserAvatar);
            userMapper.enroll(user);
            return user;
        } catch (Exception e) {
            log.error("用户注册时出现内部错误！");
            e.printStackTrace();
            throw e;
        }

    }


    /**
     * @Description: 退出登录
     * @author: ling
     * @date: 2022/3/27
     * @Return: com.ling.module1sbbyyds.interaction.Return.Result
     */
    public ResultVo loginOut() {
        Map<String, Object> userData = UserThreadLocal.get();
        String token = userData.get("token").toString();

        //删除redis中的token,登录记忆将不存在
        if (redis.delete(token)) {
            return ResultVo.success(true);
        } else {
            return ResultVo.fail("退出失败！");
        }
    }

    /**
     * @param phone:
     * @Description: 查看手机是否已绑定
     * @author: ling
     * @date: 2022/3/27
     * @Return: com.ling.module1sbbyyds.interaction.Return.Result
     */
    public ResultVo findPhone(String phone) {

        try {
            if (!phone.matches(this.phoneStyle)) {
                return ResultVo.fail("手机号格式有误！");
            }
            if ("".equals(phone)) {
                ResultVo.fail("手机号为空！");
            }

            if (userMapper.findUserByPhone(phone) == null) {
                return ResultVo.fail("手机已绑定！");
            }
            return ResultVo.success(true);
        } catch (Exception e) {

            log.error("查看手机是否已绑定时出现错误！");
            e.printStackTrace();
            return ResultVo.fail();
        }
    }


    /**
     * @param phone: 手机号
     * @Description: 获取验证码
     * @author: ling
     * @date: 2022/3/27
     * @Return: com.ling.module1sbbyyds.interaction.Return.Result
     */
    public ResultVo returnCode(String phone) throws IOException {
        if (phone == null || "".equals(phone)) {
            return ResultVo.fail("手机号为空！");
        }
        if (!phone.matches(this.phoneStyle)) {
            return ResultVo.fail("手机号格式有误！");
        }
        // 服务器生成验证码！
        //Integer code = validateCode.getCode();

        // 阿里云服务器验证码
        String code = validateCode.Albbyun(phone);

        // 腾讯服务器验证码
        //String code = validateCode.tenxunCode(phone);

        redis.opsForValue().set(phone, code.toString(), 2, TimeUnit.MINUTES);
        return ResultVo.success(code);

    }
}
